/*
 * Copyright [2022] [https://www.xiaonuo.vip]
 *
 * Snowy采用APACHE LICENSE 2.0开源协议，您在使用过程中，需要注意以下几点：
 *
 * 1.请不要删除和修改根目录下的LICENSE文件。
 * 2.请不要删除和修改Snowy源码头部的版权声明。
 * 3.本项目代码可免费商业使用，商业使用请保留源码和相关描述文件的项目出处，作者声明等。
 * 4.分发源码时候，请注明软件出处 https://www.xiaonuo.vip
 * 5.不可二次分发开源参与同类竞品，如有想法可联系团队xiaonuobase@qq.com商议合作。
 * 6.若您的项目无法满足以上几点，需要更多功能代码，获取Snowy商业授权许可，请在官网购买授权，地址为 https://www.xiaonuo.vip
 */
package cn.lixunims.ims.modular.inventory.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.lixunims.ims.modular.basics.entity.ImsProduct;
import cn.lixunims.ims.modular.basics.entity.ImsWarehouse;
import cn.lixunims.ims.modular.basics.service.ImsProductService;
import cn.lixunims.ims.modular.basics.service.ImsWarehouseService;
import cn.lixunims.ims.modular.inventory.param.ImsInventoryChangeLogAddParam;
import cn.lixunims.ims.modular.inventory.param.ImsInventoryChangeLogEditParam;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import cn.lixunims.common.enums.CommonSortOrderEnum;
import cn.lixunims.common.exception.CommonException;
import cn.lixunims.common.page.CommonPageRequest;
import cn.lixunims.ims.modular.inventory.entity.ImsInventoryChangeLog;
import cn.lixunims.ims.modular.inventory.mapper.ImsInventoryChangeLogMapper;
import cn.lixunims.ims.modular.inventory.param.ImsInventoryChangeLogIdParam;
import cn.lixunims.ims.modular.inventory.param.ImsInventoryChangeLogPageParam;
import cn.lixunims.ims.modular.inventory.service.ImsInventoryChangeLogService;

import java.util.ArrayList;
import java.util.List;

/**
 * 库存变动日志Service接口实现类
 *
 * @author YouDong
 * @date  2024/09/19 15:03
 **/
@Service
public class ImsInventoryChangeLogServiceImpl extends ServiceImpl<ImsInventoryChangeLogMapper, ImsInventoryChangeLog> implements ImsInventoryChangeLogService {

    @Autowired
    private ImsWarehouseService warehouseService;
    @Autowired
    private ImsWarehouseService imsWarehouseService;
    @Autowired
    private ImsProductService imsProductService;


    @Override
    public Page<ImsInventoryChangeLog> page(ImsInventoryChangeLogPageParam imsInventoryChangeLogPageParam) {
        QueryWrapper<ImsInventoryChangeLog> queryWrapper = new QueryWrapper<ImsInventoryChangeLog>().checkSqlInjection();
        // 分类
        if (ObjectUtil.isNotEmpty(imsInventoryChangeLogPageParam.getWareId())) {
            String wareId = imsInventoryChangeLogPageParam.getWareId();
            if (StrUtil.isNotBlank(wareId) && !wareId.equals("0")) {
                // 获取所有子分类ID
                List<String> productTypeIds = getAllChildTypeIds(wareId);
                productTypeIds.add(wareId); // 包括当前分类
                queryWrapper.lambda().in(ImsInventoryChangeLog::getWareId, productTypeIds);
            }
        }


        // 单据类型
        queryWrapper.lambda().eq(StrUtil.isNotBlank(imsInventoryChangeLogPageParam.getOperationType()), ImsInventoryChangeLog::getOperationType, imsInventoryChangeLogPageParam.getOperationType());

        if(ObjectUtil.isAllNotEmpty(imsInventoryChangeLogPageParam.getSortField(), imsInventoryChangeLogPageParam.getSortOrder())) {
            CommonSortOrderEnum.validate(imsInventoryChangeLogPageParam.getSortOrder());
            queryWrapper.orderBy(true, imsInventoryChangeLogPageParam.getSortOrder().equals(CommonSortOrderEnum.ASC.getValue()),
                    StrUtil.toUnderlineCase(imsInventoryChangeLogPageParam.getSortField()));
        } else {
            queryWrapper.lambda().orderByAsc(ImsInventoryChangeLog::getId);
        }

        Page<ImsInventoryChangeLog> page = this.page(CommonPageRequest.defaultPage(), queryWrapper);
        List<ImsInventoryChangeLog> records = page.getRecords();


        // 关联仓库信息
        List<String> wareIds = CollStreamUtil.toList(records, ImsInventoryChangeLog::getWareId);
        List<ImsWarehouse> warehouseList = new ArrayList<>();
        if (ObjectUtil.isNotEmpty(wareIds)) {
            warehouseList = imsWarehouseService.lambdaQuery().in(ImsWarehouse::getWareId, wareIds).list();
        }

        // 关联商品信息
        List<String> productIds = CollStreamUtil.toList(records, ImsInventoryChangeLog::getProductId);
        List<ImsProduct> productList = new ArrayList<>();
        if (ObjectUtil.isAllNotEmpty(productIds)) {
            productList = imsProductService.lambdaQuery().in(ImsProduct::getProductId, productIds).list();
        }



        // 批量查询关联信息
        List<ImsWarehouse> finalWarehouseList = warehouseList;
        List<ImsProduct> finalProductList = productList;
        records.forEach(imsRealTimeInventory -> {
            // 关联供应商，商品，仓库
            imsRealTimeInventory.setProduct(finalProductList.stream().filter(imsProduct -> imsProduct.getProductId().equals(imsRealTimeInventory.getProductId())).findFirst().orElse(null));
            imsRealTimeInventory.setWarehouse(finalWarehouseList.stream().filter(ware -> ware.getWareId().equals(imsRealTimeInventory.getWareId())).findFirst().orElse(null));
        });





        return page;
    }
    /**
     * 获取某个分类的所有子分类 ID
     * @param productTypeId
     * @return
     */
    private List<String> getAllChildTypeIds(String productTypeId) {
        List<String> childIds = new ArrayList<>();
        // 获取直接子分类
        List<ImsWarehouse> childTypes = warehouseService.list(new QueryWrapper<ImsWarehouse>()
                .lambda().eq(ImsWarehouse::getParentId, productTypeId));

        for (ImsWarehouse childType : childTypes) {
            String childId = childType.getWareId();
            childIds.add(childId);
            // 递归获取子分类的子分类
            List<String> grandChildIds = getAllChildTypeIds(childId);
            childIds.addAll(grandChildIds);
        }

        return childIds;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void add(ImsInventoryChangeLogAddParam imsInventoryChangeLogAddParam) {
        ImsInventoryChangeLog imsInventoryChangeLog = BeanUtil.toBean(imsInventoryChangeLogAddParam, ImsInventoryChangeLog.class);
        this.save(imsInventoryChangeLog);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void edit(ImsInventoryChangeLogEditParam imsInventoryChangeLogEditParam) {
        ImsInventoryChangeLog imsInventoryChangeLog = this.queryEntity(imsInventoryChangeLogEditParam.getId());
        BeanUtil.copyProperties(imsInventoryChangeLogEditParam, imsInventoryChangeLog);
        this.updateById(imsInventoryChangeLog);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(List<ImsInventoryChangeLogIdParam> imsInventoryChangeLogIdParamList) {
        // 执行删除
        this.removeByIds(CollStreamUtil.toList(imsInventoryChangeLogIdParamList, ImsInventoryChangeLogIdParam::getId));
    }

    @Override
    public ImsInventoryChangeLog detail(ImsInventoryChangeLogIdParam imsInventoryChangeLogIdParam) {
        return this.queryEntity(imsInventoryChangeLogIdParam.getId());
    }

    @Override
    public ImsInventoryChangeLog queryEntity(String id) {
        ImsInventoryChangeLog imsInventoryChangeLog = this.getById(id);
        if(ObjectUtil.isEmpty(imsInventoryChangeLog)) {
            throw new CommonException("库存变动日志不存在，id值为：{}", id);
        }
        return imsInventoryChangeLog;
    }
}
